//Author:       Heath Cazeau
//Date:         3/9/2011
//Class:        Software Engineering
//Project:      Jaz Interpreter
//File:         InstructionSet.h

#ifndef INSTSET_H
#define INSTSET_H
#include <iostream>
#include <string>
#include <stack>
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include "Instruction.h"

using namespace std;

namespace operations
{
    class Arithmetic
    {
        public:
            void static add(stack<string> &input);
            void static subtract(stack<string> &input);
            void static multiply(stack<string> &input);
            void static divide(stack<string> &input);
            void static modulus(stack<string> &input);
    };

    class Comparison
    {
        public:
            void static lessThan(stack<string> &input);
            void static lessThanOrEqual(stack<string> &input);
            void static greaterThan(stack<string> &input);
            void static greaterThanOrEqual(stack<string> &input);
            void static equal(stack<string> &input);
            void static notEqual(stack<string> &input);
    };

    class Output
    {
        public:
            void static print(stack<string> &input);
            void static show(string input);
    };

    class Branch
    {
        public:
            static Instruction* goTo(map<string, Instruction *> labelLoc, string argument);
            static Instruction* goTrue(stack<string> &input, map<string, Instruction *> labelLocs, string argument, Instruction * current);
            static Instruction* goFalse(stack<string> &input, map<string, Instruction *> labelLocs, string argument, Instruction * current);
            static Instruction * halt();
    };

    class Logical
    {
        public:
            void static logicalAnd(stack<string> &input);
            void static logicalOr(stack<string> &input);
            void static logicalNot(stack<string> &input);
    };

    class StackManipulation
    {
        public:
            void static push(stack<string> &input, string str);
            void static pop(stack<string> &input);
            void static rvalue(stack<string> &input, map<string, int>& RMem, string var);
            void static lvalue(stack<string> &input, string var);
            void static assign(stack<string> &input, map<string, int>& LMem);
            void static copy(stack<string> &input);
    };
}
class Support
{
    public:
        int static strToInt(string &str);
        string static intToStr(int num);
        string static intptrToStr(int* ptr);
        int static compare(int a, int b);
     //   template<typename T, typename U>
    //    bool static DoesVariableExist(map<T,U> memory, T key);
};
/*template<typename T, typename U>
bool Support::DoesVariableExist(map<T,U> memory,T key)
{
    bool output = false;
    if(memory.find(key) != memory.end())
    {
        output = true;
    }
    return output;
}*/

#endif
